﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GeoUtils
{
    public enum BoundPolygonType
    {
        POLYGON, 
        LINE, 
        POINT
    };

    public class BoundPolygon
    {
        private double[][] latitudes;
        private double[][] longitudes;
        private BoundPolygonType bpt;

        public BoundPolygonType Type
        {
            get { return bpt; }
            set { bpt = value; }
        }

        public double[][] Latitudes
        {
            get { return latitudes; }
        }

        public double[][] Longitudes
        {
            get { return longitudes; }
        }

        public BoundPolygon(double[][] latitudes, double[][] longitudes, BoundPolygonType type)
        {
            this.latitudes = latitudes;
            this.longitudes = longitudes;
            bpt = type;
        }

        /// <summary>
        /// Determines whether this region contains the specified point.
        /// </summary>
        public bool ContainsPoint(LatLong point)
        {
            bool containsPoint = false;

            // Check whether each polygon contains the point.  If an odd number of
            // polygons contain the point, then the point lies within the region.
            for (int polygon = 0; polygon < latitudes.GetLength(0); polygon++)
            {
                double[] polygonLatitudes = latitudes[polygon];
                double[] polygonLongitudes = longitudes[polygon];

                // This algorithm is from Wm. Randolph Franklin -- see details and license:
                // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
                for (int i = 0, j = polygonLatitudes.Length - 1; i < polygonLatitudes.Length; j = i++)
                {
                    if ((((polygonLatitudes[i] <= point.Latitude) && (point.Latitude < polygonLatitudes[j])) ||
                         ((polygonLatitudes[j] <= point.Latitude) && (point.Latitude < polygonLatitudes[i]))) &&
                        (point.Longitude < (polygonLongitudes[j] - polygonLongitudes[i]) *
                                           (point.Latitude - polygonLatitudes[i]) /
                                           (polygonLatitudes[j] - polygonLatitudes[i]) + polygonLongitudes[i]))
                    {
                        containsPoint = !containsPoint;
                    }
                }
            }
            return containsPoint;
        }

    }
}
